package com.zr.planClass.service.impl;

import com.zr.planClass.mapper.PlanClassMapper;
import com.zr.planClass.model.*;
import com.zr.planClass.service.PlanClassService;
import com.zr.util.*;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created by 非常狂躁的猪 on 2019/12/20.
 */
@Service
public class PlanClassServiceImpl implements PlanClassService {
    @Autowired
    private PlanClassMapper planClassMapper;

    @Override
    @Transactional   //一定要注意打上事务注解
    public ResultVo add(@Valid PlanClassAddVo planClassAddVo) {


        ResultVo resultVoYanZheng= yanZheng(planClassAddVo);
        if (!resultVoYanZheng.getSuccess()){
            return resultVoYanZheng;
        }


        PlanClassVo planClassVo = new PlanClassVo();
        BeanUtils.copyProperties(planClassAddVo,planClassVo);
        Date nowDate = new Date();
        planClassVo.setCreateName("张三");
        planClassVo.setCreateTime(nowDate);
        planClassVo.setUpdateName("张三");
        planClassVo.setUpdateTime(nowDate);
        planClassMapper.addPlanClass(planClassVo);

        return ResultBuilderVo.success();
    }

    public ResultVo yanZheng(PlanClassAddVo planClassAddVo){
        //根据前端传过来的名称查询数据库,查看是否存在
        int nameCount =  planClassMapper.queryByName(planClassAddVo.getName());
        if (nameCount >0){
            return ResultBuilderVo.error(ErrorMessageClass.PLANLASSSADD); //ResultVo只是用来返回的,对这个类进行单纯的赋值操作
        }
        //根据前端传过来的编码查询数据库,查看是否存在
        int codeCount =  planClassMapper.queryByCode(planClassAddVo.getCode());
        if (codeCount >0){
            return ResultBuilderVo.error("编码已经存在"); //ResultVo只是用来返回的,对这个类进行单纯的赋值操作
        }

        return ResultBuilderVo.success();
    }

    @Override
    @Transactional
    public ResultVo update(@Valid PlanClassUpdateVo planClassUpdateVo) {
        PlanClassUpdateVo getPlanByid = planClassMapper.queryById(planClassUpdateVo.getId());//判断id是否存在

        if (getPlanByid == null){
            return ResultBuilderVo.error(ErrorMessageClass.CODEISNO);
        }

        PlanClassUpdateVo getPlanByName = planClassMapper.getPlanByName(planClassUpdateVo.getName()); //判断修改的名称是否存在,但是,可以为自己
        if (getPlanByName != null ){
            if ( !getPlanByName.getId().equals(planClassUpdateVo.getId()) ){
                return ResultBuilderVo.error(ErrorMessageClass.PLANLASSSADD);
            }
        }
        //接着就进行修改
        PlanClassVo planClassVo = new PlanClassVo();
        //BeanUtils.copyProperties(planClassAddVo,planClassVo);
        BeanUtils.copyProperties(planClassUpdateVo,planClassVo);
        Date date = new Date();
        planClassVo.setUpdateTime(date);
        planClassVo.setUpdateName("张飞");


       Integer version = planClassMapper.update(planClassVo);

       if (version == 0){
           return ResultBuilderVo.error("请刷新后重试");
       }

        return ResultBuilderVo.success();
    }

    @Override
    public ResultVo queryOnePlan(Integer id) {
        PlanClassUpdateVo planClassUpdateVo1 = planClassMapper.queryById(id);
        if (planClassUpdateVo1 != null ){
            return ResultBuilderVo.success(planClassUpdateVo1);
        }


        return ResultBuilderVo.success(planClassUpdateVo1);
    }

    @Override
    public ResultVo queryAllPlan(PlanClassSelectVo planClassSelectVo) {
        //1.查询条数
        //2.查询数据
        System.out.println("aaaaaaaaaaaa"+planClassSelectVo.getOffset());
        List<PlanClassVo> planClassVoList = planClassMapper.queryAllPlan(planClassSelectVo);
        if (!CollectionUtils.isEmpty(planClassVoList)){
            for(PlanClassVo planClassVo:planClassVoList){
                if (!planClassVo.getStatus()){
                    planClassVo.setStatusName("禁用");
                }
                if (planClassVo.getStatus()){
                    planClassVo.setStatusName("启用");
                }

            }
        }
        int count = planClassMapper.queryCount(planClassSelectVo);
        AllRecords allRecords = new AllRecords();
        allRecords.setDataList(planClassVoList);
        allRecords.setTotalNumber(count);
        allRecords.setPageIndex(planClassSelectVo.getPageIndex());
        allRecords.setPageSize(planClassSelectVo.getPageSize());
        allRecords.resetTotalNumber(count);
        return ResultBuilderVo.success(allRecords);
    }

    @Override
    public ResultVo updateStatusById(@Valid PlanClassUpdateStatus planClassUpdateStatus) {

        int countId = planClassMapper.updateStatusQueryById(planClassUpdateStatus.getId());

        if (countId <= 0){
            return  ResultBuilderVo.error(ErrorMessageClass.IDISNO);
        }

        PlanClassVo planClassVo = new PlanClassVo();
        BeanUtils.copyProperties(planClassUpdateStatus,planClassVo);
        Date date = new Date();
        planClassVo.setUpdateTime(date);
        planClassVo.setUpdateName("张三");
        planClassMapper.updateStatusById(planClassVo);
        return ResultBuilderVo.success();
    }

    @Override
    public ResultVo InquiryIntroduction(MultipartFile file) throws Exception {
      //    1.给用户提供导入模板
        //  2.提示版本问题,询问产品经理支持哪中版本的导入格式,使用2007版本的导入模板,根据版本的不同,poi导入技术的读取方式不同
        if (!file.getOriginalFilename().contains("xlsx")){
            return ResultBuilderVo.error("文件必须是2007版本的!");
        }
        //  3.模板是否是需要导入的模板,验证模板是否正确
        XSSFWorkbook workbook = new XSSFWorkbook(file.getInputStream());
        //获取单元格中的信息at0是获取sheet1中的数据.
        XSSFSheet sheet = workbook.getSheetAt(0);
        System.out.println(sheet.getRow(sheet.getFirstRowNum()).getCell(0));
        if (!String.valueOf(sheet.getRow(sheet.getFirstRowNum()).getCell(0)).equals("计划大类导入模板")){
            return ResultBuilderVo.error("模板错误,请检查模板!");
        }
        List<PlanClassVo> planClassVoList = new ArrayList<>();
        //遍历excel表格中的所有数据,从第五行开始读取,没有数据时终止遍历.
        for (int i = sheet.getFirstRowNum()+4;i<=sheet.getLastRowNum();i++){
            //读取每一行的数据
            XSSFRow xssfRow = sheet.getRow(i);
            if (xssfRow!= null){

                String test1 = String.valueOf(xssfRow.getCell(1)).trim(); //获取这一行的第一列的数据,
                String test2 = String.valueOf(xssfRow.getCell(2)).trim(); //获取这一行的第二列的数据,
                String test3 = String.valueOf(xssfRow.getCell(3)).trim(); //获取这一行的第三列的数据,

                if (!test1.equals("")&&!test1.equals("null")
                        || !test2.equals("")&&!test2.equals("null")
                       || !test3.equals("")&&!test3.equals("null")){
                    //把每一行的数据放入到实体类中
                    ResultVo<PlanClassVo> inquiryImportVo = build(xssfRow);
                    if (!inquiryImportVo.getSuccess()){
                        return inquiryImportVo;
                    }
                    //把实体类中的数据放到list集合中
                    planClassVoList.add(inquiryImportVo.getData());
                }

            }


        }


        return ResultBuilderVo.success(planClassVoList);
    }

    @Override
    public ResultVo export(HttpServletResponse response, String code, String name, Integer status)throws Exception {
        //        检查需求，是否需要按照条件导出数据，如果有条件，根据条件查询数据，把数据插入到excel表格中，导出数据即可。如果没有条件，注意：要设置默认导出条数，当数据过多时设置默认导出10000条。
//        3.转换数据，把表中存在的数字转化为相应的汉字。

        //把数据查出来
        PlanClassSelectVo planClassSelectVo = new PlanClassSelectVo();
        planClassSelectVo.setCode(code);
        planClassSelectVo.setName(name);
        planClassSelectVo.setStatus(status);
        List<PlanClassVo> planClassVoList = planClassMapper.queryExport(planClassSelectVo);
        //验证条数
        if (planClassVoList.size()>10000){
            return ResultBuilderVo.error("最多只能导出10000条数据");
        }
        //数据转换
        for (PlanClassVo planClassVo:planClassVoList){
            Integer status2 = planClassVo.getStatus()== true? 1:0;
            System.out.println("aaaaaaaaaaaa"+status2);
            System.out.println("bbbbbbbbbbbb"+PlanClassEnum.getName(status2));
            planClassVo.setStatusName(PlanClassEnum.getName(status2));
        }

        //把数据写入excel表格中
        //输出到浏览器

        //获取响应输出流
        ServletOutputStream out = response.getOutputStream();
        //给输出文件设置名称
        POIClass.toPackageOs(response, "计划大类导出");
        //读取模板中的数据
        InputStream in = ExportUtil.toPackageIn("templates/计划大类导出模板.xlsx");
        //根据模板的数据、把查询出来的数据给摸版SHeet1组中的数据赋值、把excel输出到浏览器上
        writeDataToExcel(in, "Sheet1", planClassVoList, out);
        if (in != null) {
            in.close();
            out.close();
        }

        return ResultBuilderVo.success();
    }

    // 由于此方法不能通用, 所以单独写在这里
    private void writeDataToExcel(InputStream in, String sheetName,
                                  List<PlanClassVo> resultList, ServletOutputStream out) throws Exception {
        //POi读取模板
        XSSFWorkbook wb = new XSSFWorkbook(in);
        //读取sheet1中的数据
        Sheet sheet = wb.getSheet(sheetName);
        if (sheet != null) {
            //向sheet1中赋值，设置样式
            toResultListValueInfo(sheet, resultList);
        }
        //把数据写入到输出流中
        wb.write(out);
        //关闭poi方法
        wb.close();
    }

    /**
     * 插入excel表中项目信息
     *
     * @param sheet
     */
    private void toResultListValueInfo(Sheet sheet, List<PlanClassVo> plantList) {
        //从第4行开始赋值
        int row_column = 5;
        //遍历数据集合
        for (PlanClassVo obj : plantList) {
            //创建一行的方法
            Row row = sheet.createRow(row_column);
            // 给第一列序号赋值赋值
            POIClass.toCellValue(row,0, obj.getId() + "");
            // 给第二列编码赋值
            POIClass.toCellValue(row, 1, obj.getCode() + "");
            // 给第3列名称赋值
            POIClass.toCellValue(row, 2, obj.getName() + "");
            // 给状态赋值
            POIClass.toCellValue(row, 3, obj.getStatusName() + "");
        /*    //给描述赋值
            POIClass.toCellValue(row, 4, obj.getRemark() + "");*/
            row_column++;
        }
    }


    private ResultVo build(XSSFRow xssfRow){
        PlanClassVo planClassVo = new PlanClassVo();

        planClassVo.setCode(String.valueOf(xssfRow.getCell(1)));
        planClassVo.setName(String.valueOf(xssfRow.getCell(2)));
        planClassVo.setStatusName(String.valueOf(xssfRow.getCell(3)));
        planClassVo.setRemark(String.valueOf(xssfRow.getCell(4)));

        return ResultBuilderVo.success(planClassVo);
    }



}



























